Function loaddefaultpals(fileset:Int, poffset:Int[],sets:Int)' as integer)
	Local v:Short' as Short
	Local f:String = GamePath+ "defpal" +fileset+".bin"
	Local pal:Int[16]
	If FileType(f)=1 Then
		Local fh:TStream'DIM fh as integer = FREEFILE
		fh = ReadFile(f)'OPEN f For BINARY as #fh
		For Local i:Int = 0 To sets
			If Eof(fh) Then
				CloseFile(fh)
				Return
			EndIf
			v = ReadShort(fh)'GET #fh, 1 + i * 2, v<--- eh?
			poffset[i] = v
			'DebugLog "Pal: V "+v
			If DefPalette[poffset[i]] = Null Then
				DefPalette[poffset[i]] = New Palette256
			EndIf
			If DefPalette[poffset[i]].loaded = False Then
				getpal16 (DefPalette[poffset[i]].col,0,poffset[i])
				getpal16 (DefPalette[poffset[i]].col,1,poffset[i])
				DefPalette[poffset[i]].loaded = True
			EndIf
			Rem
			For Local ii:Int = 0 To 15
				pal[ii] = DefPalette[poffset[i]].col[ii]
			Next
			
			For Local ii:Int = 0 To 7
				DefPalette[poffset[i]].col[ii*2]  = pal[ii+7]
			Next
			For Local ii:Int = 0 To 7
				DefPalette[poffset[i]].col[(ii*2)+1]  = pal[ii]
			Next
			End Rem
		Next
		CloseFile(fh)
	Else
		'guessdefaultpals fileset, poffset(), sets
	End If
End Function

Function Palette256_new_from_buffer:Palette256(pal:Int[],po:Int)
	Local ret:Palette256 = New Palette256
	Local word:Int' as integer
	'ret = allocate(SizeOf(Palette16))

	For Local i:Int = 0 To 15
		'palettes are interleaved like everything else
		word = pal[(po + i) / 2]	' get color from palette
		If (po + i) Mod 2 = 1 Then
			ret.col[i] = (word & $ff00) Shr 8
		Else
			ret.col[i] = word & $ff
		End If
	Next
	Return ret
End Function

Function changepal (palval:Int, palchange:Int, workpal:Int[],aindex:Int)

'storepal16 workpal(), aindex, palval
'palval = bound(palval + palchange, 0, 32767)
getpal16(workpal, aindex, palval)

End Function

Function getpal16 (array:Int[], aoffset:Int,foffset:Int, autotype:Int=-1,sprite:Int=0)
	Local buf:Int[8]' as integer
	Local defaultpal:Int' as integer
	Local i:Int' as integer
	If RPGLump = Null Then Return
	RPGLump.loadrecord(buf, Lower(GamePath+Game +".pal"), 8, 0)
	'DebugLog "Color Buffer: "+buf[0]+" Offset: "+buf[1]+" vs set offset: "+foffset
	If buf[0] = 4444 Then '--check magic number
		If buf[1] >= foffset And foffset >= 0 Then
			'palette is available
			RPGLump.loadrecord(buf, Lower(GamePath+Game +".pal"), 8, 1+foffset)
			'loadrecord buf(), game & ".pal", 8, 1 + foffset
			'If aoffset = 0 Then
			'	aoffset = 1
			'Else
			'	aoffset = 0
			'EndIf
			
			For i = 0 To 7
				array[ (i*2)+1] = MasterPalette[0].col[((buf[i] & $ff00) Shr 8)]
				array[(i*2)] = MasterPalette[0].col[(buf[i] & $ff) ]
				
				'DebugLog "col: "+((buf[i] & $ff00) Shr 8)+" @ "+(aoffset * 8 + i)
			Next
			
			Return
		ElseIf foffset = -1 Then
			'load a default palette
			If autotype >= 0 Then
				'defaultpal = getdefaultpal(autotype, sprite)
				If defaultpal > -1 Then
					'Recursive
					'getpal16 array(), aoffset, defaultpal
					Return 'Exit SUB
				End If
			End If
		End If
		'palette is out of range, return blank
		DebugLog "Palette out of range"
		For i = 0 To 7
			array[aoffset * 8 + i] = 0
			DebugLog "Else col: "+buf[i]+" @ "+(aoffset * 8 + i)
		Next
	Else '--magic number not found, palette is still in BSAVE format
		DebugLog "Palette in BSAVE format "
		Local xbuf:Int[100 * 8]' as integer
		RPGLump.xbload (GamePath+Game +".pal",xbuf, "16-color palettes missing " )
		'xbload game + ".pal", xbuf(), "16-color palettes missing from " + sourcerpg
		For i = 0 To 7
			array[aoffset * 8 + i] = xbuf[foffset * 8 + i]
		Next 
	End If

End Function

Function loadpalette(palnum:Int)
	Local pal:RGBP[256]
	
	If palnum < 0 Then
	 	DebugLog "loadpalette: invalid palnum " + palnum
		 palnum = 0
	End If
	If Not FileType(GamePath + "palettes.bin") = 1Then
		 '.MAS fallback, palnum ignored because it doesn't matter
		 'Local oldpalbuf:Int[767]' as integer
		 'xbload game + ".mas", oldpalbuf(), "master palette missing from " + sourcerpg
		 'convertpalette oldpalbuf(), pal()
	Else
		 Local headsize:Short, recsize:Short
		 Local palbuf:Byte[768]' as UBYTE
		
		 Local fh:TStream 'DIM fh as integer = FREEFILE
		 fh = ReadFile(GamePath + "palettes.bin")'OPEN workingdir + SLASH + "palettes.bin" For BINARY as #fh
		 headsize = ReadShort(fh)'GET #fh, , headsize
		recsize = ReadShort(fh)' GET #fh, , recsize
		For Local i:Int = 0 To  767'(recsize * (palnum + headsize + 1))-1
			palbuf[i] = ReadByte(fh)
		Next
		'GET #fh, recsize * palnum + headsize + 1, palbuf()
		 CloseFile(fh)
		 For Local i:Int = 0 To 255
			pal[i] = New RGBP
		 	 pal[i].r = palbuf[i * 3]
		 	 pal[i].g = palbuf[i * 3 + 1]
		 	 pal[i].b = palbuf[i * 3 + 2]
			DebugLog "Color: "+i+" for palette: "+palnum+" is  R: "+pal[i].r+" G: "+pal[i].g+" B: "+pal[i].b
			If i = 0 Then
				MasterPalette[palnum].col[i] = ARGB(0,0,0,0) 'make first transparent
			Else
				MasterPalette[palnum].col[i] = ARGB(255,pal[i].r,pal[i].g,pal[i].b)
			EndIf
		 Next
	End If
	'Uncomment the line below if you want the palette in text format for updating load_default_master_palette
	'dump_master_palette_as_hex pal()
End Function


'Obsolete function
Function loadset:TPixmap(file:String,i:Int,l:Int,bsize:Int)
' i = index, l = line (only if reading to screen buffer)
	Local f:TStream ' as integer
	Local idx:Int' as integer
	Local bi:Int' as integer
	Local ub:Byte ' as ubyte
	Local toggle:Int' as integer
	Local sptr:Byte' as ubyte Ptr
	Local bptr:Int[bsize]
	DebugLog "Check file: "+file
	If Not FileType(file) = 1 Then 
		DebugLog "File does not exist"
		Return Null
	EndIf
	If i < 0 Then 
		DebugLog "loadset: attempt to read index " + i + " of " + file
		Return Null
	Else
		DebugLog "loadset: attempt to read index " + i + " of " + file 
	EndIf
	'f = freefile
	f = ReadFile(file)'open fil For binary access read as #f
	SeekStream( f,(i*bsize) + 1 )
	'seek #f, (i*bsize) + 1
	'this is a horrible hack to get 2 bytes per integer, even though
	'they are 4 bytes long in FB
	bi = 0
	toggle = 0
	'If bpage >= 0 Then
	
		'read to screen 
		'sptr = vpages(wrkpage)->image
		'sptr = sptr + (vpages(wrkpage)->pitch * l)
		'idx = bsize
		'While idx > vpages(wrkpage)->w
		'	fget(f, , sptr, vpages(wrkpage)->w)
		'	idx -= vpages(wrkpage)->w
		'	sptr += vpages(wrkpage)->pitch
		'Wend
		'fget(f, , sptr, idx)
	'Else
		DebugLog "buffer size to read = " + bsize
		'Local text:TPixmap = CreatePixmap(320,200,PF_RGB888)
		'ClearPixels( text,ARGB(0,0,0,0) )
		Local ww:Int = 0
		Local hh:Int = 0
		For idx = 0 To bsize-1 ' this will be slow, will it? will it really?
			'get #f, , ub
			ub = ReadByte(f)
			'readshort would be preferable...
			If toggle = 0 Then
				bptr[bi] = ub
				toggle = 1
			Else
				bptr[bi] = bptr[bi] | (ub Shl 8)
				'check sign
				If (bptr[bi] & $8000) > 0 Then
					bptr[bi] = bptr[bi] | $ffff0000 'make -ve
				End If
				toggle = 0
				
				Local c:Int[] = IntToRGBA( bptr[bi] )
				'Local rgb:Int = RGB(Int(Float(c[0]*0.1)*255),Int(Float(c[1]*0.1)*255),Int(Float(c[2]*0.1)*255))
				'DebugLog "Color: "+bptr[bi]+" r "+c[0]+" g "+c[1]+" b "+c[2]+" a "+c[3]
				
				'text.WritePixel(ww,hh,bptr[bi])
				bi = bi + 1	
				ww = ww + 1
				If ww > 319 Then
					ww = 01
					hh = hh + 1
				EndIf							
			End If

			
			'DebugLog "Byte Processed: " + bptr[bi]
		Next
		'End Rem
		'SavePixmapPNG(text,"TESTIMAGE_"+Rand(1,100)+".png")
	'End If

	CloseFile(f)
	'Return text
	
End Function



Function loadmxs:Frame (fil:String,record:Int,dest:Frame=Null) 
'loads a 320x200 mode X format page from a file.
'You may optionally pass in existing frame to load into.
	Local f:TStream
	Local x:Int, y:Int
	Local sptr:Int' as ubyte Ptr
	Local plane:Int' as integer

	If Not FileType(fil) = 1 Then Return Null
	If record < 0 Then
		DebugLog  "loadmxs: attempted to read a negative record number " + record
		Return dest
	End If
	'f = freefile
	f = ReadFile(fil)'open fil For binary access read as #f

	If StreamSize(f) < (record + 1) * 64000 Then
		DebugLog "loadpage: wanted page " + record + "; " + fil + " is only " + StreamSize(f) + " bytes"
		CloseFile(f)
		Return dest
	End If

	'skip to index
	SeekStream( f,(record*64000) + 1)
	'seek #f, (record*64000) + 1

	If dest = Null Then
		dest = New Frame
		dest.initframe_bysize(320,200)
	End If

	'modex format, 4 planes
	'AWE GAWD I'M GONNA CRY TEARS OF BLOOD! WHO CREATED THIS FORMAT?!
	Local toggle:Int = 0
	For plane = 0 To 3
		For y = 0 To 199
			'sptr = dest->image + dest->pitch * y + plane
			sptr = 0

			For x = 0 To (80 - 1) '1/4 of a row
				If Eof(f) Then Return Null
				Local r:Byte = ReadByte(f)
				'DebugLog "Wrote pixel: "+r+" x: "+(plane+sptr)+" y: "+y
				WritePixel(dest.sprite,plane+sptr,y,MasterPalette[0].col[r])
				'get #f, , *sptr
				sptr = sptr + 4
			Next
		Next
	Next
	'for whatever reason modex reads in offset so we have to correct it
	'BAND-AID FIX
	Local tpix:TPixmap = CreatePixmap(320,200,PF_RGBA8888)
	ClearPixels( tpix )
	For Local yy:Int = 0 To 199
		For Local xx:Int = 0 To 315
		
			WritePixel(tpix,xx+4,yy,ReadPixel(dest.sprite,xx,yy))
		
		Next
	Next
	'until i figure out why modex loads funky i'll have to offset this column of pixels
	For Local yy:Int = 0 To 199
		For Local xx:Int = 1 To 4
		
			If yy > 198  Then
				WritePixel(tpix,xx-1,0,ReadPixel(dest.sprite,315+xx,yy))
			Else
				WritePixel(tpix,xx-1,yy+1,ReadPixel(dest.sprite,315+xx,yy))	
			EndIf
		
		Next
	Next
	dest.sprite = tpix
	
	'SavePixmapPNG(dest.sprite,"Modex_"+record+".png")
	CloseFile(f)
	Return dest
End Function